package cn.vivi.seckill.service.impl;

import cn.vivi.seckill.exception.GlobalException;
import cn.vivi.seckill.mapper.UserMapper;
import cn.vivi.seckill.pojo.User;
import cn.vivi.seckill.service.UserService;
import cn.vivi.seckill.util.CookieUtils;
import cn.vivi.seckill.util.MD5Utils;
import cn.vivi.seckill.util.UUIDUtils;
import cn.vivi.seckill.util.ValidatorUtil;
import cn.vivi.seckill.vo.LoginVo;
import cn.vivi.seckill.vo.RespBean;
import cn.vivi.seckill.vo.RespBeanEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;


@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public RespBean doLogin(LoginVo vo, HttpServletRequest request, HttpServletResponse response) {
        String phone = vo.getPhone();
        String password = vo.getPassword();
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(password)) {
            return RespBean.error(RespBeanEnum.LOGIN_ERROR_EMPTY);
        }
        if (!ValidatorUtil.isMobile(phone)) {
            return RespBean.error(RespBeanEnum.PHONE_ERROR);
        }
        // 根据手机号获取用户
        User user = userMapper.selectById(phone);
        if (Objects.isNull(user)) {
            return RespBean.error(RespBeanEnum.LOGIN_ERROR_EMPTY);
        }
        // 验证密码是否正确
        if (!MD5Utils.inputPassToDBPass(password, user.getSalt()).equals(user.getPassword())) {
           return RespBean.error(RespBeanEnum.PASSWORD_ERROR);
        }

        // 设置 Cookie
        // 因为直接使用 UUID 会导致 redis 中存储一个用户多次重复登陆的数据
        // 所以在这里做了一点改进
        String ticket = UUIDUtils.toUserTicket(request);
        // request.getSession().setAttribute(ticket, user);
        redisTemplate.opsForValue().set("user:" + ticket, user);
        CookieUtils.setCookie(request, response, "userTicket", ticket);
        return RespBean.success();
    }

    @Override
    public User getUserByCookie(String ticket, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isEmpty(ticket)) {
            return null;
        }
        User user = (User)redisTemplate.opsForValue().get("user:" + ticket);
        if (!Objects.isNull(user)) {
            CookieUtils.setCookie(request, response, "userTicket", ticket);
        }
        return user;
    }

    /**
     * 更新密码
     */
    public RespBean updatePassword(String userTicket, String password,
                                   HttpServletRequest request, HttpServletResponse response) {
        // 缓存获取数据
        User user = this.getUserByCookie(userTicket, request, response);
        if (Objects.isNull(user)) {
            throw new GlobalException(RespBeanEnum.PHONE_NO_EXIST);
        }
        // 设置
        user.setPassword(MD5Utils.inputPassToDBPass(password, user.getSalt()));
        // 更新数据库
        int result = userMapper.updateById(user);
        if (result > 0) {
            // 更新成功，删除缓存
            redisTemplate.delete("user:" + userTicket);
            return RespBean.success(RespBeanEnum.PASSWORD_UPDATE_SUCCESS);
        }
        return RespBean.error(RespBeanEnum.PASSWORD_UPDATE_FAIL);
    }
}
